package sk.tramtatiri.pages.users;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import ofc4j.model.Chart;
import ofc4j.model.axis.Label.Rotation;
import ofc4j.model.axis.XAxis;
import ofc4j.model.axis.XAxisLabels;
import ofc4j.model.axis.YAxis;
import ofc4j.model.elements.BarChart;
import ofc4j.model.elements.BarChart.Style;

import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.spring.injection.annot.SpringBean;

import sk.tramtatiri.MySession;
import sk.tramtatiri.OpenFlashChart;
import sk.tramtatiri.core.IConstants;
import sk.tramtatiri.data.dao.interfaces.UserDao;
import sk.tramtatiri.data.dao.interfaces.UserInfoDao;
import sk.tramtatiri.data.dataobjects.UserInfo;

public class UserHomePage extends UserPageTemplate {

	@SpringBean
	private UserInfoDao userInfoDao;

	@SpringBean
	private UserDao userDao;
	private WebMarkupContainer chartContainer;

	private OpenFlashChart openFlsChart = new OpenFlashChart("chart", 300, 200,
			new Chart());

	private Label noDataLabel;
	private String bmiLabelText = "0.00";
	private Label bmiLabel;
	private int height;

	public UserHomePage(final PageParameters parameters) {
		FeedbackPanel feedback0 = new FeedbackPanel("feedback0");
		feedback0.setOutputMarkupId(true);

		bmiLabel = new Label("bmiLabel", new PropertyModel(this, "bmiLabelText"));
		bmiLabel.setOutputMarkupId(true);
		
		if (((MySession) getSession()).hasPermission()) {
			height = userDao.load(
					((MySession) getSession()).getUserID()).getHeight();
			final int weight = userInfoDao
					.selectNewest(((MySession) getSession()).getUserID())
					.get(0).getWeight();
			calculateBmi(height, weight);
		}

		chartContainer = new WebMarkupContainer("chartContainer");
		chartContainer.add(feedback0);
		chartContainer.add(bmiLabel);
		
		noDataLabel = new Label("noData", "Neboli najdene ziadne data");
		chartContainer.add(noDataLabel);

		final TextField<Integer> weightInput = new TextField<Integer>(
				"weightInsert", new Model(""), Integer.class);
		weightInput.setRequired(true);

		Form<?> fastChartForm = new Form<Void>("fastChartForm") {
			@Override
			protected void onSubmit() {
				Calendar cal = Calendar.getInstance();
				cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH),
						cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);

				Date date = new Date(cal.getTimeInMillis());

				UserInfo uinfo0 = userInfoDao.findByUserAndDate(
						((MySession) getSession()).getUserID(), date);

				if (uinfo0 != null) {
					UserInfo uinfoTmp = uinfo0;
					UserInfo temp = uinfoTmp;
					uinfoTmp.setWeight(Integer.parseInt(weightInput.getInput()));

					userDao.load(((MySession) getSession()).getUserID())
							.getUserInfos().remove(temp);
					userDao.load(((MySession) getSession()).getUserID())
							.getUserInfos().add(uinfoTmp);
					calculateBmi(height, uinfoTmp.getWeight());
				} else {
					List<UserInfo> lastUInfo0 = userInfoDao
							.selectNewest(((MySession) getSession())
									.getUserID());
					UserInfo ui0 = null;
					if (!lastUInfo0.isEmpty()) {
						ui0 = lastUInfo0.get(0);
					}
					UserInfo uinfo1 = new UserInfo();
					uinfo1.setDate(new Date(cal.getTimeInMillis()));
					uinfo1.setUser(userDao.load(((MySession) getSession())
							.getUserID()));
					uinfo1.setUser_id(((MySession) getSession()).getUserID());

					uinfo1.setWeight(Integer.parseInt(weightInput.getInput()));
					uinfo1.setWaist(ui0.getWaist());
					userInfoDao.save(uinfo1);
					userDao.load(((MySession) getSession()).getUserID())
							.getUserInfos().add(uinfo1);
					calculateBmi(height, uinfo1.getWeight());
				}

				drawChart();
			}
		};
		fastChartForm.add(weightInput);
		chartContainer.add(fastChartForm);
		chartContainer.add(openFlsChart);

		if (((MySession) getSession()).hasPermission()) {
			chartContainer.setVisible(true);
			drawChart();
		} else {
			chartContainer.setVisible(false);
		}

		add(chartContainer);
	}

	private void drawChart() {
		List<UserInfo> userInfoList = userInfoDao.selectLastXDays(
				((MySession) getSession()).getUserID(), 6);
		List<Number> weights = new ArrayList<Number>();
		String[] dates = new String[userInfoList.size()];
		int i = 0;
		int maxWeight = 0;
		for (UserInfo ui : userInfoList) {
			weights.add(ui.getWeight());

			SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy");
			dates[i] = sdf.format(ui.getDate());

			if (ui.getWeight() >= maxWeight)
				maxWeight = ui.getWeight();
			i++;
		}

		YAxis yaxis = new YAxis();
		yaxis.setSteps(20);
		XAxis xaxis = new XAxis();
		XAxisLabels xaxisLab = new XAxisLabels();
		xaxisLab.setRotation(Rotation.VERTICAL);
		xaxisLab.addLabels(dates);
		xaxis.setXAxisLabels(xaxisLab);

		BarChart bar = new BarChart(Style.GLASS);
		bar.addValues(weights);
		bar.setColour("#1494A3");
		bar.setTooltip("Vaha:#val#");
		bar.setText("Vaha");
		bar.setAlpha(0.1f);
		bar.setFontSize(10);

		Chart chart = new Chart();
		chart.addElements(bar);
		chart.setBackgroundColour("#FFFFFF");
		yaxis.setMax(maxWeight + 10);
		chart.setYAxis(yaxis);
		chart.setXAxis(xaxis);

		openFlsChart = new OpenFlashChart("chart", 300, 200, chart);

		if (!userInfoList.isEmpty()) {
			openFlsChart.setVisible(true);
			noDataLabel.setVisible(false);
		} else {
			openFlsChart.setVisible(false);
			noDataLabel.setVisible(true);
		}
		boolean bool = true;

		try {
			chartContainer.remove(openFlsChart);
			bool = false;
		} catch (Exception e) {
			bool = false;
		}

		if (!bool) {
			chartContainer.add(openFlsChart);
		}
	}

	@Override
	public String getPageTitle() {
		return IConstants.PAGE_NAME;
	}

	private void calculateBmi(int height, int weight) {
		double heightValueInM = height / 100.0;
		double bmi = weight / Math.pow(heightValueInM, 2);

		int pom = (int) (bmi * 100);

		setBmiLabelText(Double.toString(pom / 100.0));
	}

	/**
	 * @return the bmiLabelText
	 */
	public String getBmiLabelText() {
		return bmiLabelText;
	}

	/**
	 * @param bmiLabelText
	 *            the bmiLabelText to set
	 */
	public void setBmiLabelText(String bmiLabelText) {
		this.bmiLabelText = bmiLabelText;
	}
}
